﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MishraReader.Entities;
using MishraReader.Services;
using MishraReader.ViewModels.AppServices;
using MishraReader.ViewModels.Settings;

namespace MishraReader.ViewModels
{
    public enum MainViewModelStatus
    {
        Disconnected,
        Connected,
        AutoConnecting,
    }

    public interface IMainViewModel
    {
    }

    public class MainViewModel : TaskViewModelBase, IMainViewModel
    {
        private readonly IWpfApplication _application;
        private readonly PropertyObserver<IGoogleReaderConnector> _connectorObserver;
        private readonly ILightWeakEventManager _eventManager;
        private readonly ICredentialProvider _credentialProvider;
        private readonly IGoogleReaderService _gService;
        private readonly Func<IMishraReaderViewModel> _readerFactory;
        private readonly Func<ISignInViewModel> _signInFactory;
        private bool _editSettings;
        private bool _isLoaded;
        private IMishraReaderViewModel _reader;
        private ISignInViewModel _signIn;

        private MainViewModelStatus _status;

        /// <summary>
        ///   Ctr
        /// </summary>
        public MainViewModel(ICredentialProvider credentialProvider,
                             IGoogleReaderService gService,
                             IWpfApplication application,
                             ILightWeakEventManager eventManager,
                             ISettingsViewModel settingsModel,
                             Func<IMishraReaderViewModel> readerFactory,
                             Func<ISignInViewModel> signInFactory
            )
        {
            _credentialProvider = credentialProvider;
            _gService = gService;
            _application = application;
            _eventManager = eventManager;
            _readerFactory = readerFactory;
            _signInFactory = signInFactory;
            Settings = settingsModel;
            _connectorObserver = PropertyObserver.Create(_gService.Connector);
            _connectorObserver.RegisterHandler(c => c.Status,
                                               c => _application.Invoke(() => ReaderStatusChanged(c.Status)));

            _eventManager.Register<string>(ApplicationMessages.NavigationMessage, NavigationRequested);

            _eventManager.Register(ApplicationMessages.Disconnected, OnDisconnected);

            _eventManager.Register(ApplicationMessages.Connected, OnConnected);

            Load();

            NavigateToRoot();
        }

        public bool EditSettings
        {
            get { return _editSettings; }
            private set
            {
                Set(ref _editSettings, value);
            }
        }

        public IMishraReaderViewModel Reader
        {
            get { return _reader; }
            private set
            {
                Set(ref _reader, value);
            }
        }


        public ISettingsViewModel Settings { get; private set; }

        public ISignInViewModel SignIn
        {
            get { return _signIn; }
            private set
            {
                Set(ref _signIn, value);
            }
        }

        /// <summary>
        ///   Status of user
        /// </summary>
        public MainViewModelStatus Status
        {
            get { return _status; }
            internal set
            {
                if (_status != value)
                {
                    Set(ref _status, value);
                    OnStatusChanged();
                }
            }
        }

        /// <summary>
        ///   Dtr
        /// </summary>
        public override void Cleanup()
        {
          //  _connectorObserver.UnregisterAllHandlers();
            base.Cleanup();
        }

        /// <summary>
        ///   LoadAsync view model & autoconnect
        /// </summary>
        public async void Load()
        {
            if (_isLoaded)
                return;

            _isLoaded = true;

            if (!string.IsNullOrEmpty(_credentialProvider.Login))
            {
                Status = MainViewModelStatus.AutoConnecting;

                try
                {
                    await _gService.Connector.Connect(_credentialProvider.Login, _credentialProvider.Password);
                }
                catch(Exception)
                {
                    // TODO : connection failure feedback
                }
            }
            else
            {
                Status = MainViewModelStatus.Disconnected;
            }
        }

        private async void NavigateToRoot()
        {
            EditSettings = false;

            switch (Status)
            {
                case MainViewModelStatus.Connected:
                    SignIn = null;

                    if (Reader == null)
                    {
                        Reader = _readerFactory();
                        await Reader.LoadAsync();
                    }
                    //ChangeView(_mishraReaderView);
                    break;
                case MainViewModelStatus.AutoConnecting:
                    // ChangeView(new AutoSignInView());
                    break;
                default:
                    //  ChangeView(new DisconnectedView());
                    if (SignIn == null)
                    {
                        SignIn = _signInFactory();
                        SignIn.ShowDialog();
                    }
                    break;
            }
        }

        private void NavigationRequested(String viewName)
        {
            switch (viewName)
            {
                case "Root":
                    NavigateToRoot();
                    break;

                case "Settings_SharingServices":
                    Settings.SelectedTabIndex = 1;
                    Settings.SelectedHeaderIndex = 0;
                    EditSettings = true;
                    break;

                case "Settings_BookmarkServices":
                    Settings.SelectedTabIndex = 2;
                    Settings.SelectedHeaderIndex = 0;
                    EditSettings = true;
                    break;

                case "Settings":
                    Settings.SelectedTabIndex = 0;
                    Settings.SelectedHeaderIndex = 0;
                    EditSettings = true;
                    break;
            }
        }

        private void OnConnected()
        {
            Status = MainViewModelStatus.Connected;
        }

        private void OnDisconnected()
        {
            Status = MainViewModelStatus.Disconnected;
        }

        private void OnStatusChanged()
        {
            if (Status == MainViewModelStatus.Disconnected)
            {
                if (Reader != null)
                    Reader.Cleanup();

                Reader = null;
            }

            NavigateToRoot();
        }

        private async void ReaderStatusChanged(GoogleReaderConnectorStatus status)
        {
            switch (status)
            {
                case GoogleReaderConnectorStatus.NotConnected:
                    Status = MainViewModelStatus.Disconnected;
                    break;

                case GoogleReaderConnectorStatus.Connected:
                    Reader = _readerFactory();
                    await Reader.LoadAsync();

                    Status = MainViewModelStatus.Connected;
                    break;
            }
        }
    }
}